import React, { useState, useEffect, useCallback } from 'react'
import { Resizable } from 'react-resizable';
import { Table, Form, Input, Checkbox, Pagination, Modal, notification, Row, DatePicker } from 'antd'
import moment from 'moment'
import { getDate } from '../../../utils/action';
const CheckboxGroup = Checkbox.Group

const isInvalidObject = (value) => {
  return value === '' || value === undefined || value === null || value.length === 0
}
/**
 * 消息通知框---失败或警告
 * @param {*} type 传入消息框类型（warning,error)
 * @param {*} content 消息内容
 */
const openModalMessage = (type, content) => {
  Modal[type]({
    content: content,
    maskClosable: true,
    autoFocusButton: null,
  });
};
/**
 * 消息通知框--仅限成功时使用
 * @param {*} message 消息内容
 */
const openSuccessModal = (message) => {
  notification['success']({
    message: message,
  });
};
/**
 * 对比字符串
 * @param {*} a 前一个字符串
 * @param {*} b 后一个字符串
 * @returns {number}
 */
function compareString(a, b) {
  const s1 = a == null ? '' : a.toString();
  const s2 = b == null ? '' : b.toString();
  return s1.localeCompare(s2);
}

/**
 * 对比日期
 * @param {*} a 前一个日期
 * @param {*} b 后一个日期
 * @returns {number}
 */
function compareDate(a, b) {
  const s1 = a == null ? '' : new Date(a).getTime();
  const s2 = b == null ? '' : new Date(b).getTime();
  return s1 - s2;
}

/**
 * 对比数字
 * @param {*} a 前一个数字
 * @param {*} b 后一个数字
 * @returns {number}
 */
function compareNum(a, b) {
  const s1 = a == null ? 0 : Number(a);
  const s2 = b == null ? 0 : Number(b);
  return s1 - s2;
}
/**
 * 获取变量类型
 * @param {*} o 
 * @returns {string}
 */
function getType(o) {
  return Object.prototype.toString.call(o).slice(8, -1);
}
/***
 * 可伸缩列
 */
const ResizeableTitle = props => {
  const { onResize, width, ...restProps } = props;

  if (!width) {
    return <th {...restProps} />;
  }

  return (
    <Resizable
      width={width}
      height={0}
      onResize={onResize}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  );
};

/***
 * 可编辑行
 */
const EditableContext = React.createContext();

const EditableRow = ({ form, index, ...props }) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component {
  state = {
    editing: false,
    endOpen: false,
  };
  onChange1 = (a) => {
    const { record, dataIndex, handleSave } = this.props
    if (a !== null) {
      let dates1 = getDate(a._d)
      let dataIndexs = { [dataIndex]: dates1 }
      handleSave({ ...record, ...dataIndexs });
      const editing = false
      const endOpen = false
      this.setState({ editing, endOpen });
    } else {
      let dates1 = a
      let dataIndexs = { [dataIndex]: dates1 }
      handleSave({ ...record, ...dataIndexs });
      const editing = false
      const endOpen = false
      this.setState({ editing, endOpen });
    }
  }
  // onOpenChange = (status) => {
  //   const then = this
  //   const { record, dataIndex, handleSave } = this.props
  //   if (status === false) {
  //     if (then.input.props.value !== null) {
  //       console.log(then.input);
  //       let dates = getDate(then.input.props.value._d)
  //       let dataIndexs = { [dataIndex]: dates }
  //       // handleSave({ ...record, ...dataIndexs });
  //     }
  //   }
  // }
  renderCell = form => {
    this.form = form;
    const { children, dataIndex, record, title, required } = this.props;
    return <Form.Item style={{ margin: 0 }}>
      {form.getFieldDecorator(dataIndex, {
        rules: [
          {
            required: required === true ? true : false,
            message: `请输入${title}`,
          },
        ],
        initialValue: children[2] !== null && children[2] !== undefined ? moment(children[2], 'YYYY/MM/DD') : null,
      })(
        <DatePicker ref={node => (this.input = node)}
          onChange={this.onChange1}
          // showTime
          // onOpenChange={this.onOpenChange}
          // onOk={this.onoks}
          placeholder={`请输入${title}`}
          format={'YYYY/MM/DD'} />
      )
      }
    </Form.Item>
  };

  render() {
    const {
      editable,
      dataIndex,
      title,
      record,
      index,
      handleSave,
      children,
      required,
      ...restProps
    } = this.props;
    return (
      <td {...restProps}>
        {editable ? (
          <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
        ) : (
          children
        )}
      </td>
    );
  }
}

/***
 * 设置分页
 * @param {*} loadData 一个返回当前pageNum和pageSize的值,便于操作父组件的刷新
 * @param {*} pageNum 当前页码
 * @param {*} pageSize 每页条数
 * @param {*} total 总共条数
 * @param {*} pageSizeOptions 指定每页可以显示多少条
 */

const BasicPagination = (props) => {
  const { loadData, pageNum, pageSize, total } = props
  const pageSizeOptions = props.pageSizeOptions ? props.pageSizeOptions : ['10', '20', '30', '40']
  const [pageNumProps, setPageNum] = useState(pageNum)
  const [pageSizeProps, setPageSize] = useState(pageSize)
  const [totalProps, setTotal] = useState(total)
  // 分页变化
  const onHandleChange = (page, size) => {
    setPageNum(page);
    setPageSize(size);
    loadData(page, size);
  };
  useEffect(() => {
    setPageNum(pageNum);
    setPageSize(pageSize);
    setTotal(total);
  }, [pageNum, pageSize, total])
  return (
    <div style={{ margin: 10, textAlign: 'center' }}>
      <Pagination
        current={pageNumProps}
        pageSize={pageSizeProps}
        showQuickJumper
        size="small"
        showSizeChanger
        total={totalProps}
        onShowSizeChange={onHandleChange}
        onChange={onHandleChange}
        pageSizeOptions={pageSizeOptions}
        showTotal={(total, range) =>
          `当前 ${range[0]}-${range[1]} 条 共 ${total} 条记录`
        }
      />
    </div>
  )
}


/**
 * 表格
 * @param {*} rowKey 唯一值
 * @param {*} columns 列表title部分---需为一个可变值，放在state里面
 * @param {*} dataSource 列表主体内容--需为一个可变值，放在state里面
 * @param {*} allowRowEdit 是否允许筛选列名
 * @param {*} allowEditable 是否允许编辑行数据
 * @param {*} allowDrafting 是否允许拖拽
 * 以下是columns中需要注意的参数
 * @param {*} editable 为true时可以编辑该列数据
 * @param {*} required 为true时可以设定该列数据为必填项
 * @param {*} sorter 固定用法sorter: (a, b) => compareNum(a.sort, b.sort)  不同类型数据调用不同函数
 * @param {*} 序号排列 固定用法render: (text, record, index) => <span>{(pageNum - 1) * (pageSize) + index + 1}</span>
 * 以下是注意项
 * 1、如果要允许拖拽，需给columns每一列（除最后一列）设置宽度，并且宽度需要是number类型；
 * 2、表格默认不分页，如果要分页，有单独的分页组件已封装好，为保证样式统一，请用分页组件 <BasicPagination />
 */
const TableCustomize = React.memo(function TableCustomize({ rowKey, columns, dataSource, allowRowEdit, allowEditable, allowDrafting, ...props }) {
  const rowKeyProp = rowKey ? rowKey : (row, index) => index;
  const [columnsProps, setColumnsProps] = useState([...columns])
  const [dataSourceProps, setDataSourceProps] = useState(() => dataSource)
  const [selectedColumns, setSelectedColumns] = useState(() => columns.map((item) => item.dataIndex))

  const handleResize = useCallback((index) => {
    return (e, { size }) => {
      setColumnsProps(prev => {
        const nextColumns = [...prev];
        nextColumns[index] = {
          ...nextColumns[index],
          width: size.width,
        };
        return nextColumns;
      });
    };
  }, []);

  // 设置筛选列
  const setFilterDropdown = (columns, setTableCols) => {
    const defaultCols = [...columns];
    const optCols = defaultCols.slice(-1) // 操作列
    const withoutOptCols = defaultCols.slice(0, -1) // 排除操作列之外的列
    const options = withoutOptCols.map(item => ({
      label: item.title,
      value: item.dataIndex
    }))
    let defaultChecked = options.map(item => item.value)
    const filterDropdown = () => {
      return (
        <div className={'dynamic-column'}>
          <Checkbox.Group defaultValue={defaultChecked} onChange={onColumnChange} >
            {options && options.map((item) => <Row key={item.value}>
              <Checkbox value={item.value}>{item.label}</Checkbox>
            </Row>)}
          </Checkbox.Group>
        </div>
      );
    }
    const onColumnChange = (checkedArr) => {
      setSelectedColumns([...checkedArr, optCols[0].dataIndex]);
    }
    defaultCols[defaultCols.length - 1].filterDropdown = filterDropdown;
    if (allowDrafting) {
      setTableCols(defaultCols.map((col, index) => ({
        ...col,
        onHeaderCell: column => ({
          width: column.width,
          onResize: handleResize(index),
        }),
      })));
    } else {
      setTableCols(defaultCols);
    }
  }

  const handleSave = row => {
    const newData = [...dataSource];
    const index = newData.findIndex(item => row.id === item.id);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      ...row,
    });
    allowEditable(row, newData);
    setDataSourceProps(newData);
  };
  const columnsPropsFinally = columnsProps.filter((col) => {
    return selectedColumns.indexOf(col.dataIndex) > -1;
  }).map((col, index) => {
    let colNew = { ...col }
    if (!allowRowEdit && allowDrafting) {
      colNew = {
        ...colNew,
        onHeaderCell: column => ({
          width: column.width,
          onResize: handleResize(index),
        }),
      }
    }
    if (allowEditable && colNew.editable) {
      colNew = {
        ...colNew,
        onCell: record => ({
          record,
          editable: colNew.editable,
          required: colNew.required,
          dataIndex: colNew.dataIndex,
          title: colNew.title,
          handleSave: handleSave,
        }),
      }
    }
    return colNew;
  });
  const components = {
    header: {
      cell: ResizeableTitle,
    },
    body: {
      row: EditableFormRow,
      cell: EditableCell,
    },
  };
  useEffect(() => {
    setDataSourceProps(dataSource);
  }, [dataSource]);

  useEffect(() => {
    if (allowRowEdit) {
      setFilterDropdown(columns, setColumnsProps)
    }
  }, [allowRowEdit, columns]);

  return (
    <Table
      className="x-table"
      size="small"
      rowKey={rowKeyProp}
      columns={columnsPropsFinally}
      components={components}
      dataSource={dataSourceProps}
      // loading={loadingOption}
      scroll={{ x: true }}
      {...props}
      bordered
    />
  );
});

export {
  TableCustomize,
  compareString,
  compareDate,
  compareNum,
  BasicPagination,
  openSuccessModal,
  openModalMessage,
  isInvalidObject
}
